package com.cskaoyan.service.user.impl;

import com.cskaoyan.bean.common.BaseRespVo;
import com.cskaoyan.bean.po.AdminInfoBean;
import com.cskaoyan.bean.po.InfoData;
import com.cskaoyan.bean.po.LoginUserData;
import com.cskaoyan.bean.po.MarketAdmin;
import com.cskaoyan.config.realm.MarketToken;
import com.cskaoyan.mapper.MarketPermissionMapper;
import com.cskaoyan.mapper.MarketRoleMapper;
import com.cskaoyan.service.user.AuthService;
import com.cskaoyan.util.SymmetricEncryption;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author jzp
 * @since 2022/11/21 16:35
 */
@Service
public class AuthServiceImpl implements AuthService {
    @Override
    public BaseRespVo login(String username, String password) {
        //在这里要执行登录，Subject.login
        // → Subject只能作为局部变量，不能作为全局变量
        Subject subject = SecurityUtils.getSubject();
        // 执行登录（认证）
        //UsernamePasswordToken authenticationToken = new UsernamePasswordToken(username,password);

        MarketToken authenticationToken = new MarketToken(username, password, "admin");
        try {
            // realm.doGetAuthenticationInfo
            subject.login(authenticationToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }
        if (subject.isAuthenticated()) {
            // 可以获得session信息，也可以获得其sessionId
            Session session = subject.getSession();

            // 获得Principal信息 → realm的doGetAuthorizationInfo方法构造的认证信息里的第一个参数
            MarketAdmin primaryPrincipal = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();

            LoginUserData loginUserData = new LoginUserData();
            AdminInfoBean adminInfo = new AdminInfoBean();
            adminInfo.setAvatar(primaryPrincipal.getAvatar());
            adminInfo.setNickName(primaryPrincipal.getUsername());
            loginUserData.setAdminInfo(adminInfo);
            session.setAttribute("loginState", 0);
            // loginUserData.setToken("c4d988f3-e4c5-4e46-b6ce-13b9e008ea20")
            loginUserData.setToken((String) session.getId());
            return BaseRespVo.ok(loginUserData);
        }

        Session session = subject.getSession();
        session.setAttribute("loginState", 605);
        BaseRespVo<Object> baseRespVo = new BaseRespVo<>();
        baseRespVo.setErrno(605);
        baseRespVo.setErrmsg("用户帐号或密码不正确");
        return baseRespVo;
    }

    @Autowired
    MarketRoleMapper marketRoleMapper;

    @Autowired
    MarketPermissionMapper marketPermissionMapper;

    @Override
    public BaseRespVo info(String token) {
        Subject subject = SecurityUtils.getSubject();
        if (token.equals(subject.getSession().getId())) {
            // 获得Principal信息 → realm的doGetAuthorizationInfo方法构造的认证信息里的第一个参数
            MarketAdmin primaryPrincipal = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();

            //开发完shiro之后，再整合
            InfoData infoData = new InfoData();
            infoData.setName(primaryPrincipal.getUsername());

            //根据primaryPrincipal做查询
            infoData.setAvatar(primaryPrincipal.getAvatar());

            Integer[] roleIds = primaryPrincipal.getRoleIds();
            // 得到了角色id 数组，然后循环查角色名
            String[] nameArrays = marketRoleMapper.selectByRoleIds(roleIds);
            ArrayList<String> roles = new ArrayList<>(Arrays.asList(nameArrays));
            infoData.setRoles(roles);


            ArrayList<String> perms = new ArrayList<>();
            // 查权限
            List<Integer> rIds = Arrays.asList(roleIds);
            if (rIds.contains(1)) {
                perms.add("*");
            } else {
                perms = marketPermissionMapper.selectByRoleIdsGetPerms(roleIds);
            }

            infoData.setPerms(perms);
            return BaseRespVo.ok(infoData);
        }


        return BaseRespVo.unAuthc();
    }
}
